﻿namespace MicroCloud.Extensions
{
    #region "对象映射扩展操作"
    /// <summary>
    /// 对象映射扩展操作
    /// </summary>
    public static class MapperExtensions
    {
        //字段
        private static IMapper _mapper;

        #region "方法"
        #region "设置对象映射执行者"
        /// <summary>
        /// 设置对象映射执行者
        /// </summary>
        /// <param name="mapper">映射执行者</param>
        public static void SetMapper(IMapper mapper)
        {
            mapper.CheckNotNull(nameof(mapper));
            _mapper = mapper;
        }
        #endregion
        #region "将对象映射为指定类型"
        /// <summary>
        /// 将对象映射为指定类型
        /// </summary>
        /// <typeparam name="TTarget">要映射的目标类型</typeparam>
        /// <param name="source">源对象</param>
        /// <returns>目标类型的对象</returns>
        public static TTarget MapTo<TTarget>(this object source)
        {
            CheckMapper();
            return _mapper.MapTo<TTarget>(source);
        }
        #endregion
        #region "将对象映射为指定类型"
        /// <summary>
        /// 将对象映射为指定类型
        /// </summary>
        /// <typeparam name="TSource">源类型</typeparam>
        /// <typeparam name="TTarget">目标类型</typeparam>
        /// <param name="source">源对象</param>
        /// <returns>目标类型的对象</returns>
        public static TTarget MapTo<TSource, TTarget>(this TSource source)
        {
            CheckMapper();
            return _mapper.MapTo<TSource, TTarget>(source);
        }
        #endregion
        #region "使用源类型的对象更新目标类型的对象"
        /// <summary>
        /// 使用源类型的对象更新目标类型的对象
        /// </summary>
        /// <typeparam name="TSource">源类型</typeparam>
        /// <typeparam name="TTarget">目标类型</typeparam>
        /// <param name="source">源对象</param>
        /// <param name="target">待更新的目标对象</param>
        /// <returns>更新后的目标类型对象</returns>
        public static TTarget MapTo<TSource, TTarget>(this TSource source, TTarget target)
        {
            CheckMapper();
            return _mapper.MapTo(source, target);
        }
        #endregion
        #region "将数据源映射为指定 <typeparamref name="TOutputDto"/> 的集合"
        /// <summary>
        /// 将数据源映射为指定 <typeparamref name="TOutputDto"/> 的集合
        /// </summary>
        /// <param name="source">数据源</param>
        /// <param name="membersToExpand">成员展开</param>
        public static IQueryable<TOutputDto> ToOutput<TEntity, TOutputDto>(this IQueryable<TEntity> source,
            params Expression<Func<TOutputDto, object>>[] membersToExpand)
        {
            CheckMapper();
            return _mapper.ToOutput(source, membersToExpand);
        }
        #endregion

        #region "将对象映射为指定类型的集合"
        /// <summary>
        /// 将对象映射为指定类型的集合
        /// </summary>
        /// <typeparam name="TSource">源类型</typeparam>
        /// <typeparam name="TTarget">目标类型</typeparam>
        /// <param name="source">源对象集合</param>
        /// <returns>目标类型对象集合</returns>
        public static IEnumerable<TTarget> MapToList<TSource, TTarget>(this IEnumerable<TSource> source)
        {
            return _mapper.MapToList<TSource, TTarget>(source);
        }
        #endregion
        #region "使用源类型的对象集合更新目标类型的对象集合"
        /// <summary>
        /// 使用源类型的对象集合更新目标类型的对象集合
        /// </summary>
        /// <typeparam name="TSource">源类型</typeparam>
        /// <typeparam name="TTarget">目标类型</typeparam>
        /// <param name="source">源对象集合</param>
        /// <param name="target">待更新的目标对象集合</param>
        /// <returns>更新后的目标类型对象集合</returns>
        public static IEnumerable<TTarget> MapToList<TSource, TTarget>(this IEnumerable<TSource> source, IEnumerable<TTarget> target)
        {
            return _mapper.MapToList(source, target);
        }
        #endregion

        #region "将DataReader映射为指定类型集合"
        /// <summary>
        /// 将DataReader映射为指定类型集合
        /// </summary>
        /// <typeparam name="TTarget">目标类型</typeparam>
        /// <param name="reader">DataReader对象</param>
        /// <returns>更新后的目标类型对象集合</returns>
        public static IEnumerable<TTarget> DataReaderMapTo<TTarget>(this IDataReader reader)
        {
            return _mapper.DataReaderMapTo<TTarget>(reader);
        }
        #endregion

        #endregion

        #region "私有方法"
        #region "验证映射执行者是否为空"
        /// <summary>
        /// 验证映射执行者是否为空
        /// </summary>
        private static void CheckMapper()
        {
            if (_mapper == null)
            {
                //throw new NullReferenceException(Resources.Map_MapperIsNull);
                var errMsg = I18N.T(Resources.Map_MapperIsNull);
                throw new ArgumentException(errMsg);
            }
        }
        #endregion

        #endregion

    }
    #endregion

}
